package cn.iocoder.yudao.module.reading.service.community;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import cn.iocoder.yudao.module.reading.config.CommunitySecurityConfig;
import cn.iocoder.yudao.module.reading.enums.FilePathConstants;
import cn.iocoder.yudao.module.reading.framework.util.StaticResourceUrlUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import java.util.Arrays;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants.*;

/**
 * 社区文件上传服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class CommunityUploadServiceImpl implements CommunityUploadService {

    @Resource
    private FileService fileService;

    @Resource
    private StaticResourceUrlUtils staticResourceUrlUtils;

    @Resource
    private CommunitySecurityConfig securityConfig;

    // 支持的图片格式
    private static final List<String> SUPPORTED_IMAGE_TYPES = Arrays.asList(
            "image/jpeg", "image/jpg", "image/png", "image/gif", "image/bmp"
    );

    // 图片文件扩展名
    private static final List<String> SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(
            "jpg", "jpeg", "png", "gif", "bmp"
    );

    @Override
    public String uploadPostImage(MultipartFile file, Long userId) {
        // 1. 校验文件
        if (!validateImageFile(file)) {
            throw exception(COMMUNITY_IMAGE_CHECK_FAILED, "图片格式不支持或文件过大");
        }

        try {
            // 2. 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = FileUtil.extName(originalFilename);
            String filename = generateFilename(userId, extension);

            // 3. 上传文件到文件服务
            byte[] content = file.getBytes();
            String relativePath = fileService.createFile(content, filename, FilePathConstants.COMMUNITY_POST_IMAGE_PATH, file.getContentType());

            // 4. 转换为完整URL返回给前端
            String fullUrl = staticResourceUrlUtils.toFullUrl(relativePath);

            log.info("[uploadPostImage][图片上传成功] userId: {}, filename: {}, relativePath: {}, fullUrl: {}",
                    userId, filename, relativePath, fullUrl);

            return fullUrl;

        } catch (Exception e) {
            log.error("[uploadPostImage][图片上传失败] userId: {}, filename: {}", 
                    userId, file.getOriginalFilename(), e);
            throw exception(COMMUNITY_IMAGE_CHECK_FAILED, "图片上传失败：" + e.getMessage());
        }
    }

    @Override
    public boolean validateImageFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return false;
        }

        // 1. 检查文件大小
        if (file.getSize() > FilePathConstants.MAX_COMMUNITY_POST_IMAGE_SIZE) {
            log.warn("[validateImageFile][图片文件过大] size: {}, maxSize: {}",
                    file.getSize(), FilePathConstants.MAX_COMMUNITY_POST_IMAGE_SIZE);
            return false;
        }

        // 2. 检查文件类型
        String contentType = file.getContentType();
        if (!FilePathConstants.isSupportedImageType(contentType)) {
            log.warn("[validateImageFile][图片格式不支持] contentType: {}", contentType);
            return false;
        }

        // 3. 检查文件扩展名
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isBlank(originalFilename)) {
            return false;
        }

        String extension = FileUtil.extName(originalFilename).toLowerCase();
        if (!SUPPORTED_IMAGE_EXTENSIONS.contains(extension)) {
            log.warn("[validateImageFile][图片扩展名不支持] extension: {}", extension);
            return false;
        }

        return true;
    }

    @Override
    public String generateThumbnail(String originalUrl) {
        // 这里可以实现缩略图生成逻辑
        // 暂时返回原图URL
        return originalUrl;
    }

    /**
     * 生成文件名
     */
    private String generateFilename(Long userId, String extension) {
        return String.format("user_%d_%s.%s", userId, IdUtil.fastSimpleUUID(), extension);
    }

}
